package com.pansoft.nfc.mifare.activity;

import android.app.Activity;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.nfc.NfcAdapter;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;

import com.efounder.chat.utils.AESSecretUtil;
import com.efounder.chat.utils.CommonThreadPoolUtils;
import com.efounder.constant.EnvironmentVariable;
import com.efounder.util.EnvSupportManager;
import com.pansoft.nfc.NfcAlertUtils;
import com.pansoft.nfc.acs.ApduListManager;
import com.pansoft.nfc.mifare.Common;
import com.pansoft.nfc.mifare.MCManager;
import com.pansoft.nfc.mifare.MCReader;
import com.pansoft.openplanet.R;
import com.pansoft.openplanet.account.model.BtcBean;
import com.pansoft.openplanet.account.model.EthBean;
import com.pansoft.openplanet.account.util.BTCAccountGenerator;
import com.pansoft.openplanet.account.util.EthAccountGenerator;
import com.pansoft.openplanet.activity.BleBlutoothScanActivity;
import com.pansoft.openplanet.activity.TCBaseActivity;
import com.pansoft.openplanet.bean.Account;
import com.pansoft.openplanet.bean.CardBean;
import com.pansoft.openplanet.bean.CardWalletInfo;
import com.pansoft.openplanet.bean.CreateChildWalletBean;
import com.pansoft.openplanet.constant.IPAssetsConstant;
import com.pansoft.openplanet.constant.TalkChainConstant;
import com.pansoft.openplanet.db.AccountDao;
import com.pansoft.openplanet.db.CardDao;
import com.pansoft.openplanet.manager.ColdWalletManager;
import com.pansoft.openplanet.util.PrivateKeyUtils;
import com.pansoft.openplanet.util.TCAccountManager;
import com.pansoft.openplanet.widget.TCLoadingDataView;
import com.utilcode.util.TimeUtils;

import org.json.JSONObject;

import java.io.File;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import io.reactivex.disposables.Disposable;

import static com.pansoft.nfc.NfcCommonUtils.getBlockByPosition;
import static com.pansoft.nfc.NfcCommonUtils.getReadWalletPosition;
import static com.pansoft.openplanet.util.BTCMnemonicUtils.exportBtcMnemonics;

/**
 * 直接使用手机本身NFC功能读取
 *
 * @author wang
 */
public class MifareNfcMessageActivity extends TCBaseActivity implements View.OnClickListener {

    private TextView tvTitle;
    private TextView tvStatus;
//    private GifImageView ivImage;

    private int type;
    private Button btnWrite;

    private AccountDao accountDao;
    private Account account;
    private int chainId;
    /**
     * 私钥， Eth是私钥，btc是助记词，eos是两个私钥
     */
    private String generalPrivateKey;
    /**
     * 需写入的地址
     */
    private String address;
    /**
     * 新建钱包的bean
     */
    private CreateChildWalletBean childWalletBean;
    /**
     * 是否是新建钱包
     */
    private boolean isNewCreateWallet = false;

    private String publicKey;
    private String accountName;
    private String accountAvatar;
    private String blockChainName;

    private String keyStoreDir;

    private MCManager mcManager;
    private MCReader reader;
    private CardDao cardDao;
    private CardBean cardBean;
    /**
     * 卡片开始1扇区的数据
     */
    private String startResponse;
    private int position;
    private String positionString = "";
    private String[] positions;
    private List<CardWalletInfo> cardWalletInfoList;

    private TCAccountManager tcAccountManager;
    private ColdWalletManager coldWalletManager;
    private String uid = "";

    /**
     * Nodes (stats) MCT passes through during its startup.
     * 一直循环调用
     * 是否有nfc-->是否支持m1卡-->是否启用nfc功能-->处理贴卡intent
     */
    private enum StartUpNode {
        HasNfc,
        HasMifareClassicSupport,
        HasNfcEnabled,
        HandleNewIntent
    }

    private Intent mOldIntent = null;

    /**
     * 冷热钱包转换，传入的是address
     *
     * @param context
     * @param address 写入的地址
     * @param type    创建，转换，还是读取私钥
     */
    public static void start(Context context, String address, int type) {
        Intent starter = new Intent(context, MifareNfcMessageActivity.class);
        starter.putExtra("address", address);
        starter.putExtra("createType", type);
        context.startActivity(starter);
    }

    /**
     * 创建子钱包，传入的是CreateChildWalletBean
     *
     * @param context
     * @param childWalletBean
     */
    public static void start(Context context, CreateChildWalletBean childWalletBean,
                             int type) {
        Intent starter = new Intent(context, MifareNfcMessageActivity.class);
        starter.putExtra("childWalletBean", childWalletBean);
        starter.putExtra("createType", type);
        context.startActivity(starter);
    }

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.open_planet_acitivty_blt_message);
        address = getIntent().getStringExtra("address");
        childWalletBean = (CreateChildWalletBean) getIntent().getExtras().get("childWalletBean");
        initView();
        showNfcConnecting();
        if (address == null || "".equals(address)) {
            if (childWalletBean == null) {
                return;
            }
            address = childWalletBean.getWalletAddress();
            //新建钱包
            isNewCreateWallet = true;
        }

        initData();
    }

    private void initView() {
        tvTitle = (TextView) findViewById(R.id.tv_title);
        tvStatus = (TextView) findViewById(R.id.tv_status);
//        ivImage = (GifImageView) findViewById(R.id.iv_image);

        btnWrite = (Button) findViewById(R.id.btn_write);
        btnWrite.setVisibility(View.GONE);
        btnWrite.setOnClickListener(this);

        disableButton();
    }

    private void initData() {
        accountDao = new AccountDao(this);
        account = accountDao.getAccount(address);
        //检查卡片上是否有数据，地址是否正确
//        apduMode = APDU_MODE_CHECK_ADDR;
        if (isNewCreateWallet) {
            onNewCreatedWallet();
            tvTitle.setText(R.string.op_create_cold_wallet);
            btnWrite.setText(R.string.op_create_cold_wallet);
            //设置读卡模式
        } else {
            if (account.getAccountType() == Account.ACCOUNT_TYPE_COMMON) {
                btnWrite.setText(R.string.op_convert_to_cold_wallet);
                tvTitle.setText(R.string.op_convert_to_cold_wallet);
                CommonThreadPoolUtils.execute(new Runnable() {
                    @Override
                    public void run() {
                        onConvertToCold();
                    }
                });
            } else if (account.getAccountType() == Account.ACCOUNT_TYPE_COLD) {
                btnWrite.setText(R.string.op_convert_to_hot_wallet);
                tvTitle.setText(R.string.op_convert_to_hot_wallet);
            }
        }
        type = getIntent().getIntExtra("createType", 0);
        if (type == BleBlutoothScanActivity.TYPE_READ_PRIV_KEY) {
            btnWrite.setText(R.string.open_planet_transfer);
            tvTitle.setText(R.string.open_planet_transfer);
        }
        tcAccountManager = new TCAccountManager(this);
        coldWalletManager = new ColdWalletManager(this);

    }

    /**
     * Each phase of the MCTs startup is called "node" (see {@link StartUpNode})
     * and can be started by this function. The following nodes will be
     * started automatically (e.g. if the "has NFC support?" node is triggered
     * the "has MIFARE classic support?" node will be run automatically
     * after that).
     * 一直循环调用
     * 是否有nfc-->是否支持m1卡-->是否启用nfc功能-->处理贴卡intent
     *
     * @param startUpNode The node of the startup checks chain.
     * @see StartUpNode
     */
    private void runSartUpNode(StartUpNode startUpNode) {
        switch (startUpNode) {
            case HasNfc:
                Common.setNfcAdapter(NfcAdapter.getDefaultAdapter(this));
                if (Common.getNfcAdapter() == null) {
                    NfcAlertUtils.createNfcEnableDialog(MifareNfcMessageActivity.this);
                } else {
                    runSartUpNode(StartUpNode.HasMifareClassicSupport);
                }
                break;
            case HasMifareClassicSupport:
                if (!Common.hasMifareClassicSupport(MifareNfcMessageActivity.this)) {
                    NfcAlertUtils.createNfcEnableDialog(MifareNfcMessageActivity.this);
                } else {
                    runSartUpNode(StartUpNode.HasNfcEnabled);
                }
                break;
            case HasNfcEnabled:
                Common.setNfcAdapter(NfcAdapter.getDefaultAdapter(this));
                if (!Common.getNfcAdapter().isEnabled()) {
                    NfcAlertUtils.createNfcEnableDialog(MifareNfcMessageActivity.this);
                } else {
                    // NOTE: Use MCT with internal NFC controller.
                    Common.enableNfcForegroundDispatch(this);
                    runSartUpNode(StartUpNode.HandleNewIntent);
                }
                break;
            case HandleNewIntent:
                Common.setPendingComponentName(null);
                Intent intent = getIntent();
                if (intent != null && intent.getAction() != null) {
                    boolean isIntentWithTag = intent.getAction().equals(
                            NfcAdapter.ACTION_TECH_DISCOVERED);
                    if (isIntentWithTag && intent != mOldIntent) {
                        // If MCT was called by another app or the dispatch
                        // system with a tag delivered by intent, handle it as
                        // new tag intent.
                        mOldIntent = intent;
                        onNewIntent(getIntent());
                    } else {
                        // Last node. Do nothing.
                        break;
                    }
                }
                break;
        }
    }


    /**
     * Resume by triggering MCT's startup system
     * ({@link #runSartUpNode(StartUpNode)}).
     *
     * @see #runSartUpNode(StartUpNode)
     */
    @Override
    public void onResume() {
        super.onResume();
        runSartUpNode(StartUpNode.HasNfc);
    }


    /**
     * Disable NFC foreground dispatch system.
     *
     * @see Common#disableNfcForegroundDispatch(Activity)
     */
    @Override
    public void onPause() {
        Common.disableNfcForegroundDispatch(this);
        super.onPause();
    }

    /**
     * Handle new Intent as a new tag Intent and if the tag/device does not
     * support MIFARE Classic, then run {@link }.
     *
     * @see Common#treatAsNewTag(Intent, android.content.Context)
     * @see
     */
    @Override
    public void onNewIntent(Intent intent) {
        Log.d("onNewIntent", intent.getAction());
        int typeCheck = Common.treatAsNewTag(intent, this);
        if (typeCheck == -1 || typeCheck == -2) {
            // Device or tag does not support MIFARE Classic.
            // Run the only thing that is possible: The tag info tool.
//                Intent i = new Intent(this, TagInfoTool.class);
//                startActivity(i);
        } else {
            showNfcConnectSuccess();
            readBegin();
        }
    }

    /**
     * 开始读卡
     */
    private void readBegin() {
        reader = Common.checkForTagAndCreateReader(this);
        if (reader == null) {
            showNfcFail();
            return;
        }
        mcManager = new MCManager(this, reader);
        mcManager.setMcStateListener(new MCManager.MCStateListener() {
            @Override
            public void onAuthSuccess(String cardNo, String cardType) {
                onCheckUid(cardNo, cardType);
                uid = new String(Common.hexStringToByteArray(cardNo), StandardCharsets.UTF_8).trim();
            }

            @Override
            public void onAddSucceed() {
                //添加卡片成功，继续进行读写卡等操作
                onTransactionBegin();
            }

            @Override
            public void onAddedAlready() {
                //已经添加过卡片，可以继续进行读写卡操作
                onTransactionBegin();
            }

            @Override
            public void onError(String error) {
                showNfcFail();
            }
        });
        cardDao = new CardDao(this);
        mcManager.readUidSector();
    }

    /**
     * 检查卡片uid
     *
     * @param cardNo hex十六进制数
     */
    private void onCheckUid(String cardNo, String cardType) {
        if (cardNo == null || "".equals(cardNo)) {
            showNfcFail();
            return;
        }
        try {
            //前两个字节是类型
            String type = new String(Common.hexStringToByteArray(cardType), StandardCharsets.UTF_8).trim();
            //替换掉前面的0
            type = type.replaceAll("^(0+)", "");
            //后面的是卡号
            cardNo = new String(Common.hexStringToByteArray(cardNo), StandardCharsets.UTF_8).trim();
            cardBean = cardDao.getCardBean(cardNo);
            String startResponse = mcManager.readStartSector();
            JSONObject jsonObject = new JSONObject(startResponse);
            positionString = jsonObject.optString("p");
            positions = positionString.split(",");
            mcManager.onAddCard(cardNo, type, startResponse, cardBean);
        } catch (Exception e) {
            e.printStackTrace();
            showNfcFail();
        }
    }

    /**
     * 开始处理业务，转账，转冷，转热等
     */
    private void onTransactionBegin() {
        if (cardBean == null) {
            showNfcFail();
            return;
        }
        cardWalletInfoList = cardBean.getWalletInfoList();
        if (cardWalletInfoList == null) {
            cardWalletInfoList = new ArrayList<>();
        }
        if (cardWalletInfoList.size() > 0) {
            //已存在钱包
            //找到需要写入钱包的位置
            position = mcManager.getInsertWalletPosition(cardWalletInfoList);
            if (type == BleBlutoothScanActivity.TYPE_CREATE_COLD_WALLET ||
                    (type == BleBlutoothScanActivity.TYPE_CONVERT_WALLET && account.getAccountType() == Account.ACCOUNT_TYPE_COMMON)) {
                //新建冷钱包或转换成冷钱包
                showNfcWriting();
                convertToCold();
                enableButton();
            } else if (type == BleBlutoothScanActivity.TYPE_READ_PRIV_KEY) {
                //转账，读私钥
                showNfcReading();
                //传输数据
                position = getReadWalletPosition(address, cardWalletInfoList);
                String response = mcManager.readWalletPrivKey(position);
                onReadPrivKey(response);
            } else if (type == BleBlutoothScanActivity.TYPE_CONVERT_WALLET && account.getAccountType() == Account.ACCOUNT_TYPE_COLD) {
                //转热钱包，读私钥
                showNfcReading();
                //传输数据
                position = getReadWalletPosition(address, cardWalletInfoList);
                String response = mcManager.readWalletPrivKey(position);
                onReadPrivKey(response);
            }
        } else {
            //空卡
            //可以写入钱包
            //创建冷钱
            if (type == BleBlutoothScanActivity.TYPE_CREATE_COLD_WALLET ||
                    (type == BleBlutoothScanActivity.TYPE_CONVERT_WALLET && account.getAccountType() == Account.ACCOUNT_TYPE_COMMON)) {
                position = mcManager.getInsertWalletPosition(cardWalletInfoList);
                //新建冷钱包或转换成冷钱包
                showNfcWriting();
                convertToCold();
                enableButton();
            } else {
                showEmptyCard();
            }
        }
    }

    /**
     * 处理新建钱包
     */
    private void onNewCreatedWallet() {
        chainId = childWalletBean.getChainId();
        address = childWalletBean.getWalletAddress();
        if (chainId == IPAssetsConstant.CHAIN_ID_ETH) {
            generalPrivateKey = TCAccountManager.convertTo16Radix(childWalletBean.getPrivateKey());
            blockChainName = IPAssetsConstant.ChainEnum.ETH.chainName;
        } else if (chainId == IPAssetsConstant.CHAIN_ID_BTC) {
            generalPrivateKey = childWalletBean.getMnemonic();
            blockChainName = IPAssetsConstant.ChainEnum.BTC.chainName;
        } else if (chainId == IPAssetsConstant.CHAIN_ID_EOS) {
            generalPrivateKey = childWalletBean.getPrivateKey() + "|"
                    + childWalletBean.getEosActivePriKey();
            blockChainName = IPAssetsConstant.ChainEnum.EOS.chainName;
        }
        publicKey = childWalletBean.getPublicKey();
        accountAvatar = childWalletBean.getWalletAvatar();
        accountName = childWalletBean.getWalletName();
    }

    /**
     * 处理转换钱包，从地址，本地钱包得到私钥
     */
    private void onConvertToCold() {
        if (account.getBlockChainName().equals(IPAssetsConstant.ChainEnum.ETH.chainName)) {
            chainId = IPAssetsConstant.CHAIN_ID_ETH;
            generalPrivateKey = PrivateKeyUtils.exportPrivateKey(account.getFileName(), "");
            blockChainName = IPAssetsConstant.ChainEnum.ETH.chainName;
        } else if (account.getBlockChainName().equals(IPAssetsConstant.ChainEnum.BTC.chainName)) {
            chainId = IPAssetsConstant.CHAIN_ID_BTC;
            generalPrivateKey = exportBtcMnemonics(account.getFileName());
            blockChainName = IPAssetsConstant.ChainEnum.BTC.chainName;
        } else if (account.getBlockChainName().equals(IPAssetsConstant.ChainEnum.EOS.chainName)) {
            chainId = IPAssetsConstant.CHAIN_ID_EOS;
            generalPrivateKey = PrivateKeyUtils.exportEosPrivateKey(account.getSecretPrivateKey(), "")
                    + "|" + PrivateKeyUtils.exportEosPrivateKey(account.getEosActivePriKey(), "");
            blockChainName = IPAssetsConstant.ChainEnum.EOS.chainName;
        }
        publicKey = account.getPublicKey();
        accountAvatar = account.getAccountAvatar();
        accountName = account.getAcccountName();
    }

    /**
     * 写卡成功后设置本地数据库冷钱包
     * 新建钱包，用bean里的数据，上传服务器
     * 转换钱包，使用file生成私钥等信息，再修改服务器信息
     */
    private void onWriteColdWalletSucceed(final String uid, final String cardInfo) {
        //1. 上传服务器成功后
        CommonThreadPoolUtils.execute(new Runnable() {
            @Override
            public void run() {
                if (tcAccountManager.addCardWalletToServer(uid, cardInfo, EnvironmentVariable.getProperty("tc_ethAddress"),
                        address, accountAvatar, accountName, chainId + "", position + "")) {
                    //上传成功
                    //2. 操作本地数据库
                    try {
                        String startString = ApduListManager.parseStartData(
                                positionString, cardBean.getVersion());
                        if (mcManager.writeWallet(startString, 8, 1)) {
                            saveCardWallet();
                            coldWalletManager.onChangeLocalWallet(account);
                        }
                    } catch (Exception e) {
                        e.printStackTrace();
                        runOnUiThread(new Runnable() {
                            @Override
                            public void run() {
                                showNfcFail();
                            }
                        });
                    }
                    //3.成功之后再写卡，加入完成标志位
                    runOnUiThread(new Runnable() {
                        @Override
                        public void run() {
                            onSealCardWallet();
                        }
                    });
                } else {
                    runOnUiThread(new Runnable() {
                        @Override
                        public void run() {
                            showNfcFail();
                        }
                    });
                }
            }
        });
    }

    /**
     * 转换冷钱包，写卡成功后设置本地数据库冷钱包
     */
    private void onConvertToColdWalletSucceed(final String cardInfo) {
        //1. 上传服务器成功后
        CommonThreadPoolUtils.execute(new Runnable() {
            @Override
            public void run() {
                if (tcAccountManager.convertCardWallet(EnvironmentVariable.getProperty("tc_ethAddress"), uid,
                        chainId + "", "3", address, position + "",
                        cardInfo, "", "")) {

                    //上传成功
                    //2. 操作本地数据库
                    try {
                        String startString = ApduListManager.parseStartData(
                                positionString, cardBean.getVersion());
                        if (mcManager.writeWallet(startString, 8, 1)) {
                            saveCardWallet();
                            coldWalletManager.onChangeLocalWallet(account);
                        }
                    } catch (Exception e) {
                        e.printStackTrace();
                        runOnUiThread(new Runnable() {
                            @Override
                            public void run() {
                                showNfcFail();
                            }
                        });
                    }
                    //3.成功之后再写卡，加入完成标志位
                    runOnUiThread(new Runnable() {
                        @Override
                        public void run() {
                            NfcAlertUtils.showConvertSuccess(MifareNfcMessageActivity.this);
                        }
                    });
                } else {
                    runOnUiThread(new Runnable() {
                        @Override
                        public void run() {
                            showNfcFail();
                        }
                    });
                }
            }
        });
    }

    /**
     * 处理读取秘钥
     *
     * @param response
     */
    private void onReadPrivKey(String response) {
        try {
            //长度+chainId+长度+addr+长度+privateKey
            //第3、4位是chainId
            String chainId = new String(Common.hexStringToByteArray(response.substring(2, 4)),
                    StandardCharsets.UTF_8).trim();
            //5、6位是地址长度
            int addrLength = Integer.parseInt(response.substring(4, 6), 16);
            //取地址
            String addr = new String(Common.hexStringToByteArray(response.substring(6, 6 + addrLength)),
                    StandardCharsets.UTF_8).trim();
            //私钥长度
            int privateKeyLength = Integer.parseInt(response.substring(6 + addrLength, 8 + addrLength), 16);
            //取私钥
            String encryptPrivateKey = new String(Common.hexStringToByteArray(response.substring(8 + addrLength,
                    8 + addrLength + privateKeyLength)), StandardCharsets.UTF_8).trim();
            AESSecretUtil aesSecretUtil = new AESSecretUtil(Common.NFC_WALLET_SECRET_KEY);
            String privateKey = aesSecretUtil.decrypt(encryptPrivateKey);
            if (addr.equals(address)) {
                generalPrivateKey = privateKey;
                if (type == BleBlutoothScanActivity.TYPE_READ_PRIV_KEY) {
                    Intent intent = new Intent();
                    intent.putExtra("privateKey", generalPrivateKey);
                    setResult(RESULT_OK, intent);
                    finish();
                } else {
                    onConvertToHot();
                }
            } else {
                showWrongCard();
            }
        } catch (Exception e) {
            e.printStackTrace();
            showNfcFail();
        }
    }

    private void convertToCold() {
        showNfcWriting();
        if (generalPrivateKey == null || "".equals(generalPrivateKey) || "".equals(address)) {
            showNfcFail();
            return;
        }
        CommonThreadPoolUtils.execute(new Runnable() {
            @Override
            public void run() {
                String string = ApduListManager.parseWalletData(chainId + "", address, generalPrivateKey);
                //写入钱包数据
                int startBlock = getBlockByPosition(position);
                if (mcManager.writeWallet(string, startBlock, 5)) {
                    //更新start区块信息，将新的position加入
                    int ver = 0;
                    if (!"".equals(cardBean.getVersion())) {
                        ver = Integer.valueOf(cardBean.getVersion()) + 1;
                    }
                    cardBean.setVersion(String.valueOf(ver));
                    if (!"".equals(positionString)) {
                        positionString = positionString.concat("," + position);
                    } else {
                        positionString = position + "";
                    }
                    Map<String, String> jsonMap = new HashMap<>();
                    jsonMap.put("p", positionString);
                    jsonMap.put("v", ver + "");
                    final JSONObject jsonObject = new JSONObject(jsonMap);
                    runOnUiThread(new Runnable() {
                        @Override
                        public void run() {
                            if (isNewCreateWallet) {
                                onWriteColdWalletSucceed(uid, jsonObject.toString());
                            } else {
                                onConvertToColdWalletSucceed(jsonObject.toString());
                            }
                        }
                    });
                    return;

                }
                showNfcFail();
            }
        });
    }

    /**
     * 处理转换钱包，从nfc卡上私钥恢复本地文件，上传服务器，修改数据库，nfc卡置0
     */
    private void onConvertToHot() {

        //创建目录
        keyStoreDir = TalkChainConstant.getChildAccountFilePath(this) + File.separator + EnvironmentVariable.getUserName();
        File file = new File(keyStoreDir);
        if (!file.exists()) {
            file.mkdirs();
        }
        String cardInfo = calculateHotStart();
        if (account.getBlockChainName().equals(IPAssetsConstant.ChainEnum.ETH.chainName)) {
            chainId = IPAssetsConstant.CHAIN_ID_ETH;
            restoreEth(cardInfo);
        } else if (account.getBlockChainName().equals(IPAssetsConstant.ChainEnum.BTC.chainName)) {
            chainId = IPAssetsConstant.CHAIN_ID_BTC;
            blockChainName = IPAssetsConstant.ChainEnum.BTC.chainName;
            restoreBtc(cardInfo);
        } else if (account.getBlockChainName().equals(IPAssetsConstant.ChainEnum.EOS.chainName)) {
            chainId = IPAssetsConstant.CHAIN_ID_EOS;
            blockChainName = IPAssetsConstant.ChainEnum.EOS.chainName;
        }
    }

    private String calculateHotStart() {
        //更新start区块信息，将删除钱包的pos删除掉
        int ver = 0;
        if (!"".equals(cardBean.getVersion())) {
            ver = Integer.valueOf(cardBean.getVersion()) + 1;
        }
        cardBean.setVersion(String.valueOf(ver));
        if (positions.length < 1) {
            return "";
        }
        StringBuilder sb = new StringBuilder();
        for (String s :
                positions) {
            if (Integer.valueOf(s) != position) {
                if (sb.length() > 0) {
                    sb.append(",");
                }
                sb.append(s);
            }
        }
        Map<String, String> jsonMap = new HashMap<>();
        jsonMap.put("p", sb.toString());
        jsonMap.put("v", ver + "");
        JSONObject jsonObject = new JSONObject(jsonMap);
        return jsonObject.toString();
    }

    private void deleteStartPosition(String cardInfo) {

        String startString = ApduListManager.parseStartData(cardInfo);
        if (mcManager.writeWallet(startString, 8, 1)) {
            //本地card数据库删除掉该钱包
            deleteWalletFromCardDb();
            runOnUiThread(new Runnable() {
                @Override
                public void run() {
                    NfcAlertUtils.showConvertSuccess(MifareNfcMessageActivity.this);
                }
            });
        } else {
            showNfcFail();
        }
    }

    /**
     * 转换成热钱包，或者删除冷钱包，都会将该钱包区域清零
     */
    private void writeZero() {
        final int startBlock = getBlockByPosition(position);
        CommonThreadPoolUtils.execute(new Runnable() {
            @Override
            public void run() {
                mcManager.writeWallet("", startBlock, 5);
                runOnUiThread(new Runnable() {
                    @Override
                    public void run() {
                        NfcAlertUtils.showConvertSuccess(MifareNfcMessageActivity.this);
                    }
                });
            }
        });
    }

    private void restoreEth(final String cardInfo) {
        Disposable disposable = EthAccountGenerator.recoverAccountByPrivateKey(keyStoreDir,
                generalPrivateKey, new EthAccountGenerator.GeneratorListener() {
                    @Override
                    public void generatorSuccess(final EthBean ethBean) {
                        //生成的账户放到服务器
                        CommonThreadPoolUtils.execute(new Runnable() {
                            @Override
                            public void run() {
                                String secretPrivateKey = TCAccountManager.encryptByMainPrivKey(
                                        TCAccountManager.convertTo16Radix(generalPrivateKey));
                                if (tcAccountManager.convertCardWallet(EnvironmentVariable.getProperty("tc_ethAddress"), uid,
                                        chainId + "", "1", address, position + "",
                                        cardInfo, "", secretPrivateKey)) {

                                    //上传成功
                                    //2. 操作本地数据库
                                    account.setFileName(ethBean.getKeyStoreFilePath());
                                    account.setAccountType(Account.ACCOUNT_TYPE_COMMON);
                                    accountDao.insertOrReplace(account);

                                    //不需要清零，start区块的position删除掉即可
                                    deleteStartPosition(cardInfo);
                                } else {
                                    runOnUiThread(new Runnable() {
                                        @Override
                                        public void run() {
                                            showNfcFail();
                                        }
                                    });
                                }
                            }
                        });
                    }

                    @Override
                    public void generatorFail() {
                        showNfcFail();
                    }
                });
        addDisposable(disposable);

    }

    private void restoreBtc(final String cardInfo) {
        Disposable disposable = BTCAccountGenerator.recoverBtcAccountByMnemoric(keyStoreDir,
                generalPrivateKey, new BTCAccountGenerator.GeneratorListener() {
                    @Override
                    public void generatorSuccess(final BtcBean btcBean) {
                        //生成的账户放到服务器
                        CommonThreadPoolUtils.execute(new Runnable() {
                            @Override
                            public void run() {
                                String secretPrivateKey = TCAccountManager.encryptByMainPrivKey(
                                        TCAccountManager.convertTo16Radix(generalPrivateKey));
                                if (tcAccountManager.convertCardWallet(EnvironmentVariable.getProperty("tc_ethAddress"), uid,
                                        chainId + "", "1", address, position + "",
                                        cardInfo, secretPrivateKey, "")) {

                                    //上传成功
                                    //2. 操作本地数据库
                                    if (EnvSupportManager.isSupportHDWallet()) {
                                        account.setHdBtcXpub(btcBean.getHdBtcXpub());
                                        account.setHdBtcMaxChildIndex(btcBean.getHdBtcMaxChildIndex());
                                        account.setHdBtcCurrentChildAddress(btcBean.getHdBtcCurrentChildAddress());
                                    }
                                    account.setFileName(btcBean.getKeyStoreFilePath());
                                    account.setAccountType(Account.ACCOUNT_TYPE_COMMON);
                                    account.setCreateTime(TimeUtils.getNowString());
                                    account.setSecretMnemonic(btcBean.getSecretMnemonic());
                                    accountDao.insertOrReplace(account);
                                    //不需要清零，start区块的position删除掉即可
                                    deleteStartPosition(cardInfo);
                                } else {
                                    runOnUiThread(new Runnable() {
                                        @Override
                                        public void run() {
                                            showNfcFail();
                                        }
                                    });
                                }
                            }
                        });
                    }

                    @Override
                    public void generatorFail() {
                        showNfcFail();
                    }
                });
        addDisposable(disposable);
    }

    private void enableButton() {
        btnWrite.setEnabled(true);
    }

    private void disableButton() {
        btnWrite.setEnabled(false);
    }

    /**
     * 写入完成标志位，标志钱包已完整写入
     */
    private void onSealCardWallet() {
        TCLoadingDataView.dismiss();
        //3.成功之后再写卡，加入完成标志位
        new androidx.appcompat.app.AlertDialog.Builder(this).setTitle(R.string.open_planet_create_success)
                .setCancelable(false)
                .setPositiveButton(R.string.common_text_confirm, new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialog, int which) {
                        finishAffinity();
                    }
                }).create().show();
    }

    /**
     * 保存钱包到card表
     */
    private void saveCardWallet() {
        CardWalletInfo cardWalletInfo = new CardWalletInfo();
        cardWalletInfo.setInCardPosition(position);
        cardWalletInfo.setChainId(chainId);
        cardWalletInfo.setAddress(address);
        cardWalletInfo.setWalletAvatar(accountAvatar);
        cardWalletInfo.setWalletName(accountName);
        cardWalletInfoList.add(cardWalletInfo);
        cardBean.setWalletInfoList(cardWalletInfoList);
        cardBean.setEnable(true);
        cardDao.insertOrReplace(cardBean);
    }

    /**
     * 从card表中删除钱包
     */
    private void deleteWalletFromCardDb() {
        List<CardWalletInfo> cardWalletInfos = new ArrayList<>();
        for (CardWalletInfo c :
                cardWalletInfoList) {
            if (c.getInCardPosition() != position) {
                cardWalletInfos.add(c);
            }
        }
        cardBean.setWalletInfoList(cardWalletInfos);
        cardBean.setEnable(true);
        cardDao.insertOrReplace(cardBean);
    }

    /**
     * 连接卡片
     */
    private void showNfcConnecting() {
        tvStatus.setText(R.string.op_put_card);
//        try {
//            GifDrawable gifDrawable = new GifDrawable(getResources(), R.drawable.ble_nfc_connecting);
//            gifDrawable.setLoopCount(0);
//            ivImage.setImageDrawable(gifDrawable);
//        } catch (Exception e) {
//            e.printStackTrace();
//        }
    }

    /**
     * 连接卡片失败
     */
    private void showNfcConnectFail() {
        tvStatus.setText(R.string.op_read_card_fail_put_again);
        //        dismissLoading();
        tvStatus.setText(R.string.common_text_bluetooth_connect_fail);
//        ToastUtil.showToast(BleNfcMessageActivity.this, R.string.common_text_bluetooth_connect_fail);
//        try {
//            GifDrawable gifDrawable = new GifDrawable(getResources(), R.drawable.ble_nfc_connect_fail);
//            gifDrawable.setLoopCount(1);
//            ivImage.setImageDrawable(gifDrawable);
//        } catch (Exception e) {
//            e.printStackTrace();
//        }
    }

    /**
     * 连接卡片成功
     */
    private void showNfcConnectSuccess() {
        tvStatus.setText(R.string.op_connect_card_success);
//        try {
//            GifDrawable gifDrawable = new GifDrawable(getResources(), R.drawable.ble_nfc_connect_success);
//            gifDrawable.setLoopCount(1);
//            ivImage.setImageDrawable(gifDrawable);
//        } catch (Exception e) {
//            e.printStackTrace();
//        }
    }

    /**
     * 写卡
     */
    private void showNfcWriting() {
//        try {
//            GifDrawable gifDrawable = new GifDrawable(getResources(), R.drawable.ble_nfc_write);
//            gifDrawable.setLoopCount(0);
//            ivImage.setImageDrawable(gifDrawable);
//        } catch (Exception e) {
//            e.printStackTrace();
//        }
    }

    /**
     * 读卡
     */
    private void showNfcReading() {
//        try {
//            GifDrawable gifDrawable = new GifDrawable(getResources(), R.drawable.ble_nfc_read);
//            gifDrawable.setLoopCount(0);
//            ivImage.setImageDrawable(gifDrawable);
//        } catch (Exception e) {
//            e.printStackTrace();
//        }
    }

    /**
     * 卡片操作失败
     */
    private void showNfcFail() {
        enableButton();
        tvStatus.setText(R.string.op_sth_wrong_put_card_again);
        NfcAlertUtils.showNfcFailAlert(this);
    }

    private void showEmptyCard() {
        enableButton();
        tvStatus.setText(R.string.op_no_data_put_card_again);
        NfcAlertUtils.showEmptyCardAlert(this);
    }

    /**
     * 卡片操作失败
     */
    private void showWrongCard() {
        enableButton();
        tvStatus.setText(R.string.op_incorrect_address_put_card_again);
        NfcAlertUtils.showWrongCardAlert(this);
    }


    private void showNonEmptyCard() {
        enableButton();
        tvStatus.setText(R.string.op_card_has_data_change_card);
        NfcAlertUtils.showNonEmptyCardAlert(this);
    }

    @Override
    public void onClick(View v) {
        int id = v.getId();
        if (id == R.id.iv_back) {
            finish();
        } else if (id == R.id.btn_write) {
            TCLoadingDataView.show(this, R.string.op_card_transmitting_data);
            if (type == BleBlutoothScanActivity.TYPE_READ_PRIV_KEY) {
                //转账，读私钥
                showNfcReading();
                //传输数据
                position = getReadWalletPosition(address, cardWalletInfoList);
                String response = mcManager.readWalletPrivKey(position);
                onReadPrivKey(response);

            } else if (type == BleBlutoothScanActivity.TYPE_CONVERT_WALLET) {
                if (account.getAccountType() == Account.ACCOUNT_TYPE_COMMON) {
                    //转冷钱包
                    convertToCold();
                    showNfcWriting();
                } else if (account.getAccountType() == Account.ACCOUNT_TYPE_COLD) {
                    //转热钱包，读私钥
                    showNfcReading();
                    //传输数据
                    position = getReadWalletPosition(address, cardWalletInfoList);
                    String response = mcManager.readWalletPrivKey(position);
                    onReadPrivKey(response);
                }

            }
            disableButton();
        }
    }
}
